MOSVarFix 1.02 (28 May 2020)  nemo 2018-2020

Introduction
~~~~~~~~~~~~
OS_Byte 166 has always returned the base address of the MOS variables,
i.e. the memory used to store the value of OS_Bytes &A6-&FF. The call dates
back to the BBC Micro, but works on all versions of the OS since.

 All, until the high-vector version of RO5, where it was forgotten about.

This module ensures the existing API works on all versions of the OS, and
always will. In an ideal world, bits of the API wouldn't just rot and drop
off, but this is not an ideal world, it seems.

Installation
~~~~~~~~~~~~
Copy MOSVarFix to <Boot$ToBeLoaded> (!Boot...Choices.Boot.PreDesk) and
forget about it.

Functionality
~~~~~~~~~~~~~
The module does two things:

 It ensures OS_Bytes 166 and 167 return the correct values even on high-
  vector versions of RO5.

 It write-protects the value so it cannot be accidentally changed. Writing
  to these locations was always bogus as they are informational, not actually
  functional - the Kernel accesses the MOS variables directly, not by
  indirection.

Note that the result of OS_Byte 166 is a 32bit address distributed across
R1 and R2 as is traditional for OS_Byte for historical reasons. To read the
base address of the MOS variables on any version of Arthur or RISC OS:

        MOV     R0, #166               ; base of MOS variables
        MOV     R1, #0
        MOV     R2, #255               ; read, not write
        SWI     OS_Byte
        ORR     R1, R1, R2, LSL#8      ; R1=base address

(OS_Byte 167 is less useful but will return the correct result  in a high-
vector RO5, R1 will therefore be 24bits wide).

Having read the base address (R1), the MOS variables can then be accessed in
IRQ mode, or without the overhead of a SWI. e.g. to read the "50Hz counter":

        LDRB    R0, [R1,#176]          ; OS_Byte 176 is 50Hz counter

It would have been completely trivial to maintain this API in RO5, but this
module will just have to do instead.

Caveat
~~~~~~
Having two ways of reading the same value raises the spectral question of what
happens if they return different values (that is what this module addresses).
However, OS_Byte,166 goes down the ByteV vector, so it has always been possible
for the call to return some other value for reasons unknown (per-task MOSVars
perhaps). OS_ReadSysInfo has no vector, and reason 6,71 only exists in RO5, so
strictly *it* ought to call OS_Byte,166 to avoid discrepancies. This module
does not yet implement that precaution, but I continue to bear it in mind.

Licence
~~~~~~~
Copy, distribute, reverse-engineer and adopt into a major OS of your choice,
as you see fit.

Versions
~~~~~~~~
1.00 (11 May 2018) Initial release
1.01 (11 Aug 2019) Initialisation was corrupting R7
1.02 (28 May 2020) Improved tailcall efficiency

nemo MMXX